package com.jtny.nytb.config.datafactor.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.jtny.component.enums.GenericStatusEnum;
import com.jtny.component.exception.ServiceException;
import com.jtny.component.util.Assert;
import com.jtny.component.util.BeanUtils;

import com.jtny.nytb.config.coderule.dto.ConfigRuleManagementDTO;
import com.jtny.nytb.config.coderule.dto.ConfigRuleParamRelationDTO;
import com.jtny.nytb.config.coderule.dto.ConfigRuleSequenceNumberDTO;
import com.jtny.nytb.dataparam.dao.DataParamEquipmentExtendDAO;
import com.jtny.nytb.dataparam.domain.ConfigDataParamLabelRelationDO;
import com.jtny.nytb.dataparam.domain.DataParamEquipmentExtendDO;
import com.jtny.nytb.config.datafactor.dto.*;
import com.jtny.nytb.config.datafactor.service.ConfigDataParamManagementService;
import com.jtny.nytb.config.datafactor.service.DataParamEquipmentExtendService;
import com.jtny.nytb.dataparam.property.CodeRuleProperty;
import com.jtny.nytb.equipment.dao.coderule.ConfigRuleManagementDAO;
import com.jtny.nytb.equipment.dao.coderule.ConfigRuleParamRelationDAO;
import com.jtny.nytb.equipment.dao.coderule.ConfigRuleSequenceNumberDAO;
import com.jtny.nytb.equipment.domain.coderule.ConfigRuleManagementDO;
import com.jtny.nytb.equipment.domain.coderule.ConfigRuleParamRelationDO;
import com.jtny.nytb.equipment.domain.coderule.ConfigRuleSequenceNumberDO;
import com.jtny.nytb.equipment.utils.RandomData;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 智慧能源中心 - 伍天宇
 * @package com.jtny.nytb.config.datafactor.service.impl
 * @fileName DataParamEquipmentExtendServiceImpl.java
 * @createTime 2023年11月15日 20:18
 * @Copyright© 2023 jtny
 * 江投能源技术研究院 版权所有
 */
@Service
@AllArgsConstructor
public class DataParamEquipmentExtendServiceImpl
        extends ServiceImpl<DataParamEquipmentExtendDAO, DataParamEquipmentExtendDO>
        implements DataParamEquipmentExtendService {

    @Resource
    private ConfigDataParamManagementService configDataParamManagementService;

    private CodeRuleProperty codeRuleProperty;


    private void setCode(DataParam4EquipmentDTO dataParam4Equipment) {
        String code = getCode();
        dataParam4Equipment.getDataParam4EquipmentExtend().setDataParamCode(code);
        dataParam4Equipment.getConfigDataParamManagement().setCode(code);
        dataParam4Equipment.getConfigDataParamManagement().setStatus(GenericStatusEnum.DISABLE.getValue());

        dataParam4Equipment.getDataParam4EquipmentExtend().setDataParamId(null);
        dataParam4Equipment.getConfigDataParamManagement().setId(null);
    }

    /**
     * 给参量设置code
     */
    private String getCode() {
        return queryCodeBycode(codeRuleProperty.getDataParamCodeRule(), null);
    }

    @Override
    public String queryCodeBycode(String code, String superiorCode) {
        ConfigRuleManagementDTO configRuleManagementDTO = queryBycode(code);
        StringBuilder codeString = new StringBuilder();
        if (configRuleManagementDTO == null){
            // 如果查询规则不存在，需要获取最后一条规则的顺序号。判定改规则中是否含有顺序号，如果没有进行
            ConfigRuleManagementDTO configRuleManagementDTO1 = queryLast();
            List<ConfigRuleParamRelationDTO> configRuleParamRelationList = configRuleManagementDTO1.getConfigRuleParamRelationList();
            List<ConfigRuleParamRelationDTO> sequenceNumber = configRuleParamRelationList.stream().filter(obj -> obj.getCode().equals("SequenceNumber")).collect(Collectors.toList());
            // 存在顺序号，同时顺序号存放在最后面，
            if (CollectionUtil.isNotEmpty(sequenceNumber) && sequenceNumber.get(0).getSort() == configRuleParamRelationList.size()){
                generateRuleCode(configRuleParamRelationList, codeString, superiorCode);
            }else{
                for (int i = 0; i < 5; i++) {
                    String str = RandomData.RANDOMUPPERCASEANDLOWERCASELETTERSANDNUMBERS.getMessage();
                    Random random = new Random();
                    int randomIndex = random.nextInt(str.length());
                    char randomChar = str.charAt(randomIndex);
                    codeString.append(randomChar);
                }
            }
            return codeString.toString();
        }
        List<ConfigRuleParamRelationDTO> configRuleParamRelationList = configRuleManagementDTO.getConfigRuleParamRelationList();
        generateRuleCode(configRuleParamRelationList, codeString, superiorCode);
        return codeString.toString();
    }

    private static void getRandomNumber(ConfigRuleParamRelationDTO relationDTO, StringBuilder randomString) {
        System.out.println("随机数："+ relationDTO.getCode());
        Random random = new Random();
        for (int i = 0; i < relationDTO.getDigit(); i++) {
            String str;
            if (RandomData.RANDOMLOWERCASELETTERS.getCode().equals(relationDTO.getCode())){
                str = RandomData.RANDOMLOWERCASELETTERS.getMessage();
            } else if (RandomData.RANDOMUPPERCASELETTERS.getCode().equals(relationDTO.getCode())){
                str = RandomData.RANDOMUPPERCASELETTERS.getMessage();
            } else if (RandomData.RANDOMNUMBERS.getCode().equals(relationDTO.getCode())) {
                str = RandomData.RANDOMNUMBERS.getMessage();
            } else if (RandomData.RANDOMLOWERCASELETTERSANDNUMBERS.getCode().equals(relationDTO.getCode())) {
                str = RandomData.RANDOMLOWERCASELETTERSANDNUMBERS.getMessage();
            } else if (RandomData.RANDOMUPPERCASELETTERSANDNUMBERS.getCode().equals(relationDTO.getCode())) {
                str = RandomData.RANDOMUPPERCASELETTERSANDNUMBERS.getMessage();
            } else if (RandomData.RANDOMUPPERCASEANDLOWERCASELETTERS.getCode().equals(relationDTO.getCode())) {
                str = RandomData.RANDOMUPPERCASEANDLOWERCASELETTERS.getMessage();
            } else if (RandomData.RANDOMUPPERCASEANDLOWERCASELETTERSANDNUMBERS.getCode().equals(relationDTO.getCode())) {
                str = RandomData.RANDOMUPPERCASEANDLOWERCASELETTERSANDNUMBERS.getMessage();
            }else{
                throw new ServiceException("随机数据规则有误", "B020080002");
            }
            int randomIndex = random.nextInt(str.length());
            char randomChar = str.charAt(randomIndex);
            randomString.append(randomChar);
        }
    }

    private void generateRuleCode(List<ConfigRuleParamRelationDTO> configRuleParamRelationList, StringBuilder codeString,
                                  String superiorCode) {

        for (ConfigRuleParamRelationDTO relationDTO : configRuleParamRelationList) {
            // 对于展示值，将值存入在code
            if (relationDTO.getShowName().equals(0)){
                codeString.append(relationDTO.getValue());
            }else if ("SuperiorCode".equals(relationDTO.getCode())){
                // 展示上级编码
                if (StringUtils.isBlank(superiorCode)){
                    continue;
                }
                codeString.append(superiorCode);
            }else if (relationDTO.getDigit() != null && relationDTO.getDigit() > 0) {
                StringBuilder randomString = new StringBuilder();
                if ("SequenceNumber".equals(relationDTO.getCode())){
                    // 获取当前顺序号。
                    getSequenceNumber(superiorCode, relationDTO, randomString);
                }else{
//                    展示随机数
                    getRandomNumber(relationDTO, randomString);
                }
                codeString.append(randomString.toString());
            } else if (relationDTO.getDigit() == null || 0 == relationDTO.getDigit()) {
                // 获取当前随机时间
                LocalDate localDate = LocalDate.now();
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern(relationDTO.getCode());
                String formateString = localDate.format(formatter);
                codeString.append(formateString);
            }
        }
    }


    private void getSequenceNumber(String superiorCode, ConfigRuleParamRelationDTO relationDTO, StringBuilder randomString) {
        String lastcode = superiorCode;
        if (StringUtils.isBlank(superiorCode)){  // 判定父标签是否存在，如果存在则获取父标签的数据，作为查询顺序号的条件之一。
            lastcode = "";
        }
        ConfigRuleSequenceNumberDTO configRuleSequenceNumberDTO = querylastNumber(lastcode, relationDTO.getValue());
        String numstr = configRuleSequenceNumberDTO.getSequenceNumber() + "";
        int length = numstr.length();

     /*   if (relationDTO.getDigit() == null){
            throw new ServiceException()
        }*/
        for (int i = 0; i < relationDTO.getDigit() - length; i++) {
            numstr = "0" + numstr;
        }
        randomString.append(numstr);
    }

    @Autowired
    private ConfigRuleSequenceNumberDAO configRuleSequenceNumberDAO;
    public ConfigRuleSequenceNumberDTO querylastNumber(String lastcode, String sequenceSign) {
        QueryWrapper<ConfigRuleSequenceNumberDO> wrapper = new QueryWrapper<>();
        if (lastcode == null){
            wrapper.isNull("lastcode");
        }else{
            wrapper.eq("lastcode", lastcode);
        }
        wrapper.eq("sequence_sign", sequenceSign);
        wrapper.orderByDesc("create_time");
        List<ConfigRuleSequenceNumberDO> configRuleSequenceNumberDOList = configRuleSequenceNumberDAO.selectList(wrapper);
        ConfigRuleSequenceNumberDTO configRuleSequenceNumberDTO;
        if (CollectionUtil.isEmpty(configRuleSequenceNumberDOList)){
            configRuleSequenceNumberDTO = new ConfigRuleSequenceNumberDTO();
            configRuleSequenceNumberDTO.setSequenceNumber(1);
            configRuleSequenceNumberDTO.setStep(1);
            configRuleSequenceNumberDTO.setLastcode(lastcode);
            configRuleSequenceNumberDTO.setSequenceSign(sequenceSign);
            ConfigRuleSequenceNumberDO configRuleSequenceNumberDO = new ConfigRuleSequenceNumberDO();
            configRuleSequenceNumberDO.setLastcode(configRuleSequenceNumberDTO.getLastcode());
            configRuleSequenceNumberDO.setSequenceSign(sequenceSign);
            configRuleSequenceNumberDO.setSequenceNumber(configRuleSequenceNumberDTO.getSequenceNumber());
            configRuleSequenceNumberDO.setStep(configRuleSequenceNumberDTO.getStep());
            configRuleSequenceNumberDO.setCreateTime(System.currentTimeMillis());
            configRuleSequenceNumberDO.setLastUpdateTime(System.currentTimeMillis());
            configRuleSequenceNumberDAO.insert(configRuleSequenceNumberDO);
        }else{
            configRuleSequenceNumberDTO = BeanUtils.copyToObject(configRuleSequenceNumberDOList.get(0), ConfigRuleSequenceNumberDTO.class);
        }
        ConfigRuleSequenceNumberDO configRuleSequenceNumberDO = new ConfigRuleSequenceNumberDO();
        configRuleSequenceNumberDO.setLastcode(configRuleSequenceNumberDTO.getLastcode());
        configRuleSequenceNumberDO.setSequenceSign(sequenceSign);
        configRuleSequenceNumberDO.setSequenceNumber(configRuleSequenceNumberDTO.getSequenceNumber() + configRuleSequenceNumberDTO.getStep());
        configRuleSequenceNumberDO.setStep(configRuleSequenceNumberDTO.getStep());
        configRuleSequenceNumberDO.setCreateTime(System.currentTimeMillis());
        configRuleSequenceNumberDO.setLastUpdateTime(System.currentTimeMillis());
        configRuleSequenceNumberDAO.insert(configRuleSequenceNumberDO);
        return configRuleSequenceNumberDTO;
    }

    private ConfigRuleManagementDAO ruleManagementDAO;
    private ConfigRuleParamRelationDAO ruleParamRelationDAO;
    public ConfigRuleManagementDTO queryLast() {
        // 获取单据基本信息
        QueryWrapper<ConfigRuleManagementDO> menagementWrapper = new QueryWrapper<>();
        menagementWrapper.eq("status", 0);
        menagementWrapper.orderByDesc("create_time");
        List<ConfigRuleManagementDO> configRuleManagementDOS = ruleManagementDAO.selectList(menagementWrapper);
        if (CollectionUtil.isEmpty(configRuleManagementDOS)){
            return null;
        }
        ConfigRuleManagementDO configRuleManagementDO = configRuleManagementDOS.get(0);
        ConfigRuleManagementDTO configRuleManagementDTO = BeanUtils.copyToObject(configRuleManagementDO, ConfigRuleManagementDTO.class);
        // 获取规则详情
        Long id = configRuleManagementDTO.getId();
        QueryWrapper<ConfigRuleParamRelationDO> paramWrapper = new QueryWrapper<>();
        paramWrapper.eq("rule_id", id);
        List<ConfigRuleParamRelationDO> configRuleParamRelationDOS = ruleParamRelationDAO.selectList(paramWrapper);
        List<ConfigRuleParamRelationDTO> configRuleParamRelationDTOS = BeanUtils.copyToList(configRuleParamRelationDOS, ConfigRuleParamRelationDTO.class);
        configRuleManagementDTO.setConfigRuleParamRelationList(configRuleParamRelationDTOS);
        return configRuleManagementDTO;
    }

    public ConfigRuleManagementDTO queryBycode(String code) {
        // 获取单据基本信息
        QueryWrapper<ConfigRuleManagementDO> menagementWrapper = new QueryWrapper<>();
        menagementWrapper.eq("sign", code);
        menagementWrapper.eq("status", 0);
        ConfigRuleManagementDO configRuleManagementDO = ruleManagementDAO.selectOne(menagementWrapper);
        if (configRuleManagementDO == null){
            return null;
        }
        // 获取单据关联的规则信息
        QueryWrapper<ConfigRuleParamRelationDO> wrapper = new QueryWrapper<>();
        wrapper.eq("rule_id", configRuleManagementDO.getId());
        wrapper.orderByAsc("sort");
        List<ConfigRuleParamRelationDO> configRuleParamRelationDOList = ruleParamRelationDAO.selectList(wrapper);
        // 将规则管理DO对象转为DTO对象
        ConfigRuleManagementDTO configRuleManagementDTO = BeanUtils.copyToObject(configRuleManagementDO, ConfigRuleManagementDTO.class);
        List<ConfigRuleParamRelationDTO> configRuleParamRelationDTOList = BeanUtils.copyToList(configRuleParamRelationDOList, ConfigRuleParamRelationDTO.class);
        configRuleManagementDTO.setConfigRuleParamRelationList(configRuleParamRelationDTOList);
        return configRuleManagementDTO;
    }
    /**
     * 导入数据参数设备扩展
     *
     * @param equipmentModelDataParamDTO 设备型号数据参数 DTO
     * @throws ServiceException 服务异常
     */
    @Override
    public void importDataParamEquipmentExtend(EquipmentModelDataParamDTO equipmentModelDataParamDTO) throws ServiceException {
        Map<String, String> equipmentNameModelNameMap = equipmentModelDataParamDTO.getEquipmentNameModelNameMap();
        Map<String, List<DataParam4EquipmentDTO>> mapModelNameDataParam = equipmentModelDataParamDTO.getMapModelNameDataParam();
        Map<String, DataParam4EquipmentExtendDTO> mapEquipmentExtend = equipmentModelDataParamDTO.getMapEquipmentExtend();
        Map<String, List<ConfigLabelDTO>> mapEquipmentNameLabel = equipmentModelDataParamDTO.getMapEquipmentNameLabel();
        equipmentNameModelNameMap.forEach((equipmentName, modelName) -> {
            // 按设备添加数据参数
            List<DataParam4EquipmentDTO> dataParam4EquipmentList = mapModelNameDataParam.get(modelName);
            // 有设备信息的延展数据
            DataParam4EquipmentExtendDTO equipment = mapEquipmentExtend.get(equipmentName);
            // 设备模版没有关联参量
            List<ConfigLabelDTO> configLabelList = mapEquipmentNameLabel.get(equipmentName);
            // 设备模版是关联了参量的
            if (CollUtil.isNotEmpty(dataParam4EquipmentList)) {
                List<DataParam4EquipmentDTO> toSaveBatch = buildDataParam4EquipmentList(dataParam4EquipmentList, equipment, configLabelList);
                saveDataParamEquipmentExtendBatch(toSaveBatch);
            }
        });
    }

    private List<DataParam4EquipmentDTO> buildDataParam4EquipmentList(List<DataParam4EquipmentDTO> dataParam4EquipmentList,
                                                                      DataParam4EquipmentExtendDTO equipment,
                                                                      List<ConfigLabelDTO> configLabelList) {
        List<DataParam4EquipmentDTO> result = new ArrayList<>();
        dataParam4EquipmentList.forEach(dataParam4Equipment -> {
            DataParam4EquipmentDTO dataParam4EquipmentDTO = new DataParam4EquipmentDTO();
            DataParam4EquipmentExtendDTO tempExtend = dataParam4Equipment.getDataParam4EquipmentExtend();
            DataParam4EquipmentExtendDTO extend = BeanUtils.copyToObject(tempExtend, DataParam4EquipmentExtendDTO.class);
            ConfigDataParamManagementDTO tempConfigDataParamManagement = dataParam4Equipment.getConfigDataParamManagement();
            ConfigDataParamManagementDTO configDataParamManagement = BeanUtils.copyToObject(tempConfigDataParamManagement, ConfigDataParamManagementDTO.class);
            /*if (CollUtil.isNotEmpty(configLabelList)) {
                List<ConfigLabelDTO> configLabelDTOList = configDataParamManagement.getConfigLabelDTOList();
                if (CollUtil.isNotEmpty(configLabelDTOList)) {
                    List<ConfigLabelDTO> newList = BeanUtils.copyToList(configLabelList, ConfigLabelDTO.class);
                    configDataParamManagement.setConfigLabelDTOList(setLabelList(configLabelDTOList, newList));
                } else {
                    configDataParamManagement.setConfigLabelDTOList(BeanUtils.copyToList(configLabelList, ConfigLabelDTO.class));
                }
            }*/
            configDataParamManagement.setName(equipment.getEquipmentName() + StrUtil.DASHED + configDataParamManagement.getUnifiedIdentifierName());
            dataParam4EquipmentDTO.setConfigDataParamManagement(configDataParamManagement);
            extend.setEquipmentId(equipment.getEquipmentId());
            extend.setEquipmentCode(equipment.getEquipmentCode());
            extend.setEquipmentName(equipment.getEquipmentName());
            dataParam4EquipmentDTO.setDataParam4EquipmentExtend(extend);
            result.add(dataParam4EquipmentDTO);
        });
        return result;
    }

    /**
     * 设置标签列表 （反复添加会重复）
     *
     * @param oldList 旧列表
     * @param newList 新列表
     * @return {@link List}<{@link ConfigLabelDTO}>
     */
    private List<ConfigLabelDTO> setLabelList(List<ConfigLabelDTO> oldList, List<ConfigLabelDTO> newList) {
        List<ConfigLabelDTO> result = new ArrayList<>();
        List<Long> oldIdList = oldList.stream().map(ConfigLabelDTO::getLabelItemId).collect(Collectors.toList());
        newList.removeIf(item -> oldIdList.contains(item.getLabelItemId()));
        result.addAll(oldList);
        result.addAll(newList);
        return result;
    }



    /**
     * 保存数据参数设备扩展批处理
     *
     * @param dataParam4EquipmentList 数据参数4 设备清单
     * @return {@link Boolean}
     * @throws ServiceException 服务异常
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveDataParamEquipmentExtendBatch(List<DataParam4EquipmentDTO> dataParam4EquipmentList)
            throws ServiceException {
        // 给参量设置code
        dataParam4EquipmentList.forEach(this::setCode);
        // 参量基础信息
        List<ConfigDataParamManagementDTO> dataParamManagementList = dataParam4EquipmentList.stream()
                .map(DataParam4EquipmentDTO::getConfigDataParamManagement).collect(Collectors.toList());
        // 保存参量基础信息
        Map<String, Long> mapCodeAndId = configDataParamManagementService.mapCodeAndIdSaveBatch(dataParamManagementList);
        // 设置参量id
        List<DataParamEquipmentExtendDO> toSaveList = new ArrayList<>();
        dataParam4EquipmentList.forEach(item -> {
            DataParam4EquipmentExtendDTO extend = item.getDataParam4EquipmentExtend();
            String dataParamCode = extend.getDataParamCode();
            Long dataParamId = mapCodeAndId.get(dataParamCode);
            if (ObjectUtils.isNotEmpty(dataParamId)) {
                extend.setDataParamId(dataParamId);
                toSaveList.add(BeanUtils.copyToObject(extend, DataParamEquipmentExtendDO.class));
            }
        });
        return saveOrUpdateBatch(toSaveList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateDataParamEquipmentExtendBatch(List<DataParam4EquipmentDTO> dataParam4EquipmentList) throws ServiceException {
        dataParam4EquipmentList.forEach(item -> {
            ConfigDataParamManagementDTO configDataParamManagement = item.getConfigDataParamManagement();
            configDataParamManagementService.update(configDataParamManagement);
            DataParam4EquipmentExtendDTO extend = item.getDataParam4EquipmentExtend();
            DataParamEquipmentExtendDO newToSave = BeanUtils.copyToObject(extend, DataParamEquipmentExtendDO.class);

            DataParamEquipmentExtendDO old = getOne(Wrappers.<DataParamEquipmentExtendDO>lambdaQuery()
                    .eq(DataParamEquipmentExtendDO::getDataParamId, extend.getDataParamId())
                    .last("limit 1"));
            if (ObjectUtil.isNull(old)) {
                save(newToSave);
            } else {
                newToSave.setId(old.getId());
                updateById(newToSave);
            }
        });
        return Boolean.TRUE;
    }

    /**
     * 更新设备数据参数状态
     *
     * @param equipmentId 设备 ID
     * @param status      地位
     * @throws ServiceException 服务异常
     */
    @Override
    public void updateEquipmentDataParamStatus(Long equipmentId, Integer status) throws ServiceException {
        List<Long> dataParamIdList = listDataParamIdRelation(equipmentId);
        if (ObjectUtils.isNotEmpty(dataParamIdList)) {
            configDataParamManagementService.updateStatus(status, dataParamIdList);
        }
    }

    /**
     * 更新数据参数名称
     *
     * @param equipmentId   设备 ID
     * @param equipmentName 设备名称
     * @return {@link Boolean}
     */
    @Override
    public Boolean updateDataParamName(Long equipmentId, String equipmentName) {
        List<Long> dataParamIdList = listDataParamIdRelation(equipmentId);
        if (ObjectUtils.isNotEmpty(dataParamIdList)) {
            configDataParamManagementService.updateDataParamName(equipmentName, dataParamIdList);
        }
        return Boolean.TRUE;
    }

    /**
     * 获取设备数据参数list
     *
     * @param dataParamId 参量id
     * @return {@link List}<{@link DataParam4EquipmentDTO}> 设备数据参数列表
     */
    @Override
    public DataParam4EquipmentDTO getDataParam4EquipmentByDataParamId(Long dataParamId) throws ServiceException {
        DataParam4EquipmentDTO result = new DataParam4EquipmentDTO();
        ConfigDataParamManagementDTO configDataParamManagement = configDataParamManagementService.queryById(dataParamId);
        Assert.notNull(configDataParamManagement, "数据参数不存在");
        result.setConfigDataParamManagement(configDataParamManagement);
        DataParamEquipmentExtendDO one = getOne(Wrappers.<DataParamEquipmentExtendDO>lambdaQuery()
                .eq(DataParamEquipmentExtendDO::getDataParamId, dataParamId)
                .last("limit 1"));
        if (ObjectUtils.isNotEmpty(one)) {
            DataParam4EquipmentExtendDTO extendDTO = BeanUtils.copyToObject(one, DataParam4EquipmentExtendDTO.class);
            result.setDataParam4EquipmentExtend(extendDTO);
        } else {
            DataParam4EquipmentExtendDTO extendDTO = new DataParam4EquipmentExtendDTO();
            result.setDataParam4EquipmentExtend(extendDTO);
        }
        return result;
    }


    /**
     * 获取设备数据参数list
     *
     * @param equipmentId 设备id
     * @return {@link List}<{@link ConfigDataParamManagementDTO}> 设备数据参数列表
     */
    @Override
    public List<DataParam4EquipmentDTO> listDataParamByEquipmentId(Long equipmentId) throws ServiceException {
        List<DataParam4EquipmentDTO> result = new ArrayList<>();
        List<DataParam4EquipmentExtendDTO> dataParam4EquipmentExtendList = listDataParamExtendByEquipmentId(equipmentId);
        if (CollUtil.isNotEmpty(dataParam4EquipmentExtendList)) {
            List<Long> dataParamIdList = dataParam4EquipmentExtendList.stream()
                    .map(DataParam4EquipmentExtendDTO::getDataParamId).collect(Collectors.toList());
            Map<Long, DataParam4EquipmentExtendDTO> mapExtend = dataParam4EquipmentExtendList.stream().collect(Collectors.toMap(DataParam4EquipmentExtendDTO::getDataParamId, item -> item));
            Map<Long, ConfigDataParamManagementDTO> mapConfigDataParamManagement = configDataParamManagementService.mapByIds(dataParamIdList);
            dataParamIdList.forEach(dataParamId -> {
                DataParam4EquipmentExtendDTO dataParam4EquipmentExtendDTO = mapExtend.get(dataParamId);
                ConfigDataParamManagementDTO configDataParamManagementDTO = mapConfigDataParamManagement.get(dataParamId);
                DataParam4EquipmentDTO dataParam4EquipmentDTO = new DataParam4EquipmentDTO();
                dataParam4EquipmentDTO.setConfigDataParamManagement(configDataParamManagementDTO);
                dataParam4EquipmentDTO.setDataParam4EquipmentExtend(dataParam4EquipmentExtendDTO);
                result.add(dataParam4EquipmentDTO);
            });
        }
        return result;
    }

    /**
     * 按设备代码列出数据参数
     *
     * @param equipmentCode 设备代码
     * @return {@link List}<{@link DataParam4EquipmentDTO}>
     * @throws ServiceException 服务异常
     */
    @Override
    public List<DataParam4EquipmentDTO> listDataParamByEquipmentCode(String equipmentCode) throws ServiceException {
        DataParamEquipmentExtendDO dataParamEquipmentExtendDO = baseMapper.selectOne(Wrappers.<DataParamEquipmentExtendDO>lambdaQuery()
                .eq(DataParamEquipmentExtendDO::getEquipmentCode, equipmentCode)
                .last("limit 1"));
        if (ObjectUtil.isEmpty(dataParamEquipmentExtendDO)) {
            return new ArrayList<>();
        }
        return listDataParamByEquipmentId(dataParamEquipmentExtendDO.getEquipmentId());
    }

    /**
     * 列出数据参数 ID 关系
     *
     * @param equipmentId 设备id
     * @return {@link List}<{@link Long}> 数据参量 ID 列表
     */
    @Override
    public List<Long> listDataParamIdRelation(Long equipmentId) throws ServiceException {
        List<DataParamEquipmentExtendDO> equipmentDataParamRelationDOList = baseMapper
                .selectList(Wrappers.<DataParamEquipmentExtendDO>lambdaQuery()
                        .eq(DataParamEquipmentExtendDO::getEquipmentId, equipmentId));
        return equipmentDataParamRelationDOList
                .stream()
                .map(DataParamEquipmentExtendDO::getDataParamId)
                .collect(Collectors.toList());
    }

    /**
     * 按设备 ID 列出数据参数扩展
     *
     * @param equipmentId 设备 ID
     * @return {@link List}<{@link DataParam4EquipmentExtendDTO}>
     * @throws ServiceException 服务异常
     */
    @Override
    public List<DataParam4EquipmentExtendDTO> listDataParamExtendByEquipmentId(Long equipmentId) throws ServiceException {
        List<DataParamEquipmentExtendDO> equipmentDataParamRelationDOList = baseMapper
                .selectList(Wrappers.<DataParamEquipmentExtendDO>lambdaQuery()
                        .eq(DataParamEquipmentExtendDO::getEquipmentId, equipmentId));
        return BeanUtils.copyToList(equipmentDataParamRelationDOList, DataParam4EquipmentExtendDTO.class);
    }

    /**
     * 列出数据参数 code
     *
     * @param equipmentCode 设备code
     * @return {@link List}<{@link Long}> 数据参量 ID 列表
     */
    @Override
    public List<String> listDataParamCodeRelation(String equipmentCode) throws ServiceException {
        List<DataParamEquipmentExtendDO> equipmentDataParamRelationDOList = baseMapper
                .selectList(Wrappers.<DataParamEquipmentExtendDO>lambdaQuery()
                        .eq(DataParamEquipmentExtendDO::getEquipmentCode, equipmentCode));
        return equipmentDataParamRelationDOList
                .stream()
                .map(DataParamEquipmentExtendDO::getDataParamCode)
                .collect(Collectors.toList());
    }

    /**
     * 保存关系设备数据参数
     *
     * @param equipmentDataParamRelationDTO 设备数据参数关系 DTO
     * @return {@link Boolean}
     */
    @Override
    public Boolean saveRelationEquipmentDataParam(EquipmentDataParamRelationDTO equipmentDataParamRelationDTO) throws ServiceException {
        Long equipmentId = equipmentDataParamRelationDTO.getEquipmentId();
        String equipmentCode = equipmentDataParamRelationDTO.getEquipmentCode();
        baseMapper.delete(Wrappers.<DataParamEquipmentExtendDO>lambdaQuery()
                .eq(DataParamEquipmentExtendDO::getEquipmentId, equipmentId)
                .eq(DataParamEquipmentExtendDO::getIsFromRule, Boolean.TRUE));

        List<DataParamCoreDTO> dataParamCoreList = equipmentDataParamRelationDTO.getDataParamCoreList();
        if (CollUtil.isEmpty(dataParamCoreList)) {
            return Boolean.TRUE;
        }

        List<DataParamEquipmentExtendDO> toSaveBatch = dataParamCoreList.stream().map(item -> {
            DataParamEquipmentExtendDO equipmentDataParamRelationDO = new DataParamEquipmentExtendDO();
            equipmentDataParamRelationDO.setEquipmentId(equipmentId);
            equipmentDataParamRelationDO.setEquipmentCode(equipmentCode);
            equipmentDataParamRelationDO.setIsFromRule(Boolean.TRUE);
            equipmentDataParamRelationDO.setPowerCheckDisplay(item.getPowerCheckDisplay());
            equipmentDataParamRelationDO.setDataParamId(item.getDataParamId());
            equipmentDataParamRelationDO.setDataParamCode(item.getDataParamCode());
            equipmentDataParamRelationDO.setReportIdentifier(item.getReportIdentifier());
            return equipmentDataParamRelationDO;
        }).collect(Collectors.toList());

        return saveOrUpdateBatch(toSaveBatch, 500);
    }

    /**
     * 保存关系设备数据参数
     *
     * @param dataParamCoreList 设备数据参数关系 DTO
     * @return {@link Boolean}
     */
    @Override
    public Boolean saveBatchRelationEquipmentDataParam(List<DataParamCoreDTO> dataParamCoreList) throws ServiceException {
        List<DataParamEquipmentExtendDO> toSaveBatch = BeanUtils.copyToList(dataParamCoreList, DataParamEquipmentExtendDO.class);
        return saveOrUpdateBatch(toSaveBatch, 500);
    }

    /**
     * 保存唱关系设备数据参数
     * 按规则字典 ID 移动数据参量
     *
     * @param equipmentDataParamDTO 设备数据参数 DTO
     * @return {@link Boolean}
     */
    @Override
    public Boolean saveSingRelationEquipmentDataParam(EquipmentDataParamDTO equipmentDataParamDTO) throws ServiceException {

        Long equipmentId = equipmentDataParamDTO.getEquipmentId();
        DataParamEquipmentExtendDO oldOne = baseMapper.selectOne(Wrappers.<DataParamEquipmentExtendDO>lambdaQuery()
                .eq(DataParamEquipmentExtendDO::getEquipmentId, equipmentId)
                .eq(DataParamEquipmentExtendDO::getDataParamId, equipmentDataParamDTO.getDataParamCore().getDataParamId()));
        // 更新也会使用此方法，所以需要判断是否存在 如果已经存在则不需要再次插入，更新即可
        if (ObjectUtils.isNotEmpty(oldOne)) {
            oldOne.setEquipmentCode(equipmentDataParamDTO.getEquipmentCode());
            DataParamCoreDTO dataParamCore = equipmentDataParamDTO.getDataParamCore();
            oldOne.setEquipmentId(equipmentDataParamDTO.getEquipmentId());
            oldOne.setDataParamId(dataParamCore.getDataParamId());
            oldOne.setDataParamCode(dataParamCore.getDataParamCode());
            oldOne.setReportIdentifier(dataParamCore.getReportIdentifier());
            oldOne.setPowerCheckDisplay(dataParamCore.getPowerCheckDisplay());
            return SqlHelper.retBool(baseMapper.updateById(oldOne));
        } else {
            DataParamEquipmentExtendDO equipmentDataParamRelationDO = new DataParamEquipmentExtendDO();
            equipmentDataParamRelationDO.setEquipmentId(equipmentDataParamDTO.getEquipmentId());
            equipmentDataParamRelationDO.setEquipmentCode(equipmentDataParamDTO.getEquipmentCode());
            equipmentDataParamRelationDO.setIsFromRule(Boolean.FALSE);
            DataParamCoreDTO dataParamCore = equipmentDataParamDTO.getDataParamCore();
            equipmentDataParamRelationDO.setDataParamId(dataParamCore.getDataParamId());
            equipmentDataParamRelationDO.setDataParamCode(dataParamCore.getDataParamCode());
            equipmentDataParamRelationDO.setReportIdentifier(dataParamCore.getReportIdentifier());
            equipmentDataParamRelationDO.setPowerCheckDisplay(dataParamCore.getPowerCheckDisplay());
            return SqlHelper.retBool(baseMapper.insert(equipmentDataParamRelationDO));
        }
    }

    /**
     * 获取设备数据参数关系
     *
     * @param dataParamId 数据参数 ID
     * @return
     */
    @Override
    public EquipmentDataParamDTO getRelationEquipmentDataParamByDataParamId(Long dataParamId) throws ServiceException {
        DataParamEquipmentExtendDO equipmentDataParamRelationDO = baseMapper.selectOne(Wrappers.<DataParamEquipmentExtendDO>lambdaQuery()
                .eq(DataParamEquipmentExtendDO::getDataParamId, dataParamId));

        if (ObjectUtils.isNotEmpty(equipmentDataParamRelationDO)) {
            EquipmentDataParamDTO equipmentDataParamDTO = new EquipmentDataParamDTO();
            equipmentDataParamDTO.setEquipmentId(equipmentDataParamRelationDO.getEquipmentId());
            equipmentDataParamDTO.setEquipmentCode(equipmentDataParamRelationDO.getEquipmentCode());
            equipmentDataParamDTO.setDataParamCore(new DataParamCoreDTO(equipmentDataParamRelationDO.getDataParamId(),
                    equipmentDataParamRelationDO.getDataParamCode(), equipmentDataParamRelationDO.getReportIdentifier(),
                    equipmentDataParamRelationDO.getPowerCheckDisplay()));
            return equipmentDataParamDTO;
        }
        return null;
    }

    /**
     * 按数据参数 ID 列表查询设备数据参数关系
     *
     * @param dataParamIds 数据参数 ID
     * @return {@link Map}<{@link Long}, {@link String}> key: dataParamIds
     */
    @Override
    public Map<Long, String> mapIdentifierByDataParamIds(List<Long> dataParamIds) throws ServiceException {
        List<DataParamEquipmentExtendDO> doList = baseMapper.selectList(Wrappers.<DataParamEquipmentExtendDO>lambdaQuery()
                .in(DataParamEquipmentExtendDO::getDataParamId, dataParamIds));
        return doList.stream().collect(Collectors.toMap(DataParamEquipmentExtendDO::getDataParamId, DataParamEquipmentExtendDO::getReportIdentifier));
    }

    /**
     * 按数据参数 ID 列表查询设备数据参数关系
     *
     * @param dataParamIds 数据参数 ID
     * @return {@link Map}<{@link String}, {@link EquipmentDataParamExtendDTO}> key: dataParamIds
     */
    @Override
    public Map<String, EquipmentDataParamExtendDTO> mapCodeExtendByDataParamIds(List<Long> dataParamIds) throws ServiceException {
        List<DataParamEquipmentExtendDO> equipmentDataParamRelationList = baseMapper
                .selectList(Wrappers.<DataParamEquipmentExtendDO>lambdaQuery()
                        .in(DataParamEquipmentExtendDO::getDataParamId, dataParamIds));

        if (CollUtil.isEmpty(equipmentDataParamRelationList)) {
            return new HashMap<>();
        }

        Map<String, EquipmentDataParamExtendDTO> result = new HashMap<>();
        equipmentDataParamRelationList.forEach(item -> {
            EquipmentDataParamExtendDTO equipmentDataParamExtendDTO = BeanUtils.copyToObject(item, EquipmentDataParamExtendDTO.class);
            result.put(item.getDataParamCode(), equipmentDataParamExtendDTO);
        });
        return result;
    }

    /**
     * 按设备 ID 列出数据参数 ID
     *
     * @param equipmentIdList 设备 ID 列表
     * @return {@link List}<{@link Long}>
     * @throws ServiceException 服务异常
     */
    @Override
    public List<Long> listDataParamIdByEquipmentIds(List<Long> equipmentIdList) throws ServiceException {
        List<DataParamEquipmentExtendDO> result = baseMapper.selectList(Wrappers.<DataParamEquipmentExtendDO>lambdaQuery()
                .in(DataParamEquipmentExtendDO::getEquipmentId, equipmentIdList));
        return result.stream().map(DataParamEquipmentExtendDO::getDataParamId).collect(Collectors.toList());
    }

    /**
     * 映射设备 ID 数据参数列表
     *
     * @param equipmentIdList 设备 ID 列表
     * @return {@link Map}<{@link Long}, {@link List}<{@link String}>>
     */
    @Override
    public Map<Long, List<String>> mapEquipmentIdDataParamList(List<Long> equipmentIdList) throws ServiceException {
        List<DataParamEquipmentExtendDO> equipmentDataParamRelationList = baseMapper
                .selectList(Wrappers.<DataParamEquipmentExtendDO>lambdaQuery()
                        .in(DataParamEquipmentExtendDO::getEquipmentId, equipmentIdList));
        if (CollUtil.isEmpty(equipmentDataParamRelationList)) {
            return new HashMap<>();
        }
        return equipmentDataParamRelationList.stream().collect(Collectors.groupingBy(DataParamEquipmentExtendDO::getEquipmentId,
                Collectors.mapping(DataParamEquipmentExtendDO::getDataParamCode, Collectors.toList())));
    }

    /**
     * 映射设备 ID 数据参数 ID 列表
     *
     * @param equipmentIdList 设备 ID 列表
     * @return {@link Map}<{@link Long}, {@link List}<{@link Long}>> key: equipmentId, value: dataParamIdList
     * @throws ServiceException 服务异常
     */
    @Override
    public Map<Long, List<Long>> mapEquipmentIdDataParamIdList(List<Long> equipmentIdList) throws ServiceException {
        List<DataParamEquipmentExtendDO> equipmentDataParamRelationList = baseMapper
                .selectList(Wrappers.<DataParamEquipmentExtendDO>lambdaQuery()
                        .in(DataParamEquipmentExtendDO::getEquipmentId, equipmentIdList));
        if (CollUtil.isEmpty(equipmentDataParamRelationList)) {
            return new HashMap<>();
        }
        return equipmentDataParamRelationList.stream().collect(Collectors.groupingBy(DataParamEquipmentExtendDO::getEquipmentId,
                Collectors.mapping(DataParamEquipmentExtendDO::getDataParamId, Collectors.toList())));
    }

    /**
     * 删除数据参数关系
     *
     * @param dataParamIds 数据参数 ID
     */
    @Override
    public void deleteDataParamRelation(List<Long> dataParamIds) throws ServiceException {
        baseMapper.delete(Wrappers.<DataParamEquipmentExtendDO>lambdaQuery()
                .in(DataParamEquipmentExtendDO::getDataParamId, dataParamIds));
    }

    /**
     * 按设备 ID 删除
     *
     * @param equipmentIdList 设备 ID 列表
     * @throws ServiceException 服务异常
     */
    @Override
    public void deleteByEquipmentIds(List<Long> equipmentIdList) throws ServiceException {
        baseMapper.delete(Wrappers.<DataParamEquipmentExtendDO>lambdaQuery()
                .in(DataParamEquipmentExtendDO::getEquipmentId, equipmentIdList));
    }

    /**
     * 按数据参数设备 ID 删除
     *
     * @param equipmentIdList 设备 ID 列表
     * @throws ServiceException 服务异常
     */
    @Override
    public void deleteByDataParamEquipmentIds(List<Long> equipmentIdList) throws ServiceException {
        List<Long> dataParamIdList = listDataParamIdByEquipmentIds(equipmentIdList);
        baseMapper.delete(Wrappers.<DataParamEquipmentExtendDO>lambdaQuery()
                .in(DataParamEquipmentExtendDO::getEquipmentId, equipmentIdList));
        configDataParamManagementService.deleteByIdList(dataParamIdList);
    }

    /**
     * 获取设备关联参量Code，通过设备参量上报标识和设备Code
     *
     * @param equipmentCode        设备Code
     * @param reportIdentifierList 设备上报标识
     * @return {@link List}<{@link String}> 设备关联参量Code
     */
    @Override
    public Map<String, String> mapDataParamCodeByReportIdentifierAndEquipmentCode(String equipmentCode,
                                                                                  List<String> reportIdentifierList) throws ServiceException {
        Assert.notNull(reportIdentifierList, "设备上报标识不能为空");
        LambdaQueryWrapper<DataParamEquipmentExtendDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DataParamEquipmentExtendDO::getEquipmentCode, equipmentCode);
        wrapper.in(DataParamEquipmentExtendDO::getReportIdentifier, reportIdentifierList);
        List<DataParamEquipmentExtendDO> result = baseMapper.selectList(wrapper);
        List<DataParamEquipmentExtendDO> list = Optional.ofNullable(result).orElse(new ArrayList<>());
        return list.stream().collect(Collectors.toMap(DataParamEquipmentExtendDO::getReportIdentifier, DataParamEquipmentExtendDO::getDataParamCode));
    }

    /**
     * 按数据参数 ID 映射设备 ID
     *
     * @param dataParamIds 数据参数 ID
     * @return {@link Map}<{@link Long}, {@link Long}> key: dataParamId, value: equipmentId
     * @throws ServiceException 服务异常
     */
    @Override
    public Map<Long, Long> mapEquipmentIdByDataParamIds(List<Long> dataParamIds) throws ServiceException {
        if (CollUtil.isNotEmpty(dataParamIds)) {
            List<DataParamEquipmentExtendDO> result = baseMapper.selectList(Wrappers.<DataParamEquipmentExtendDO>lambdaQuery()
                   .in(DataParamEquipmentExtendDO::getDataParamId, dataParamIds));
            return result.stream().collect(Collectors.toMap(DataParamEquipmentExtendDO::getDataParamId, DataParamEquipmentExtendDO::getEquipmentId));
        }
        return new HashMap<>();
    }

    /**
     * 按数据参数 ID 列表查询设备数据参数关系
     *
     * @param dataParamIds 数据参数 ID
     * @return {@link Map}<{@link Long}, {@link EquipmentDataParamExtendDTO}> key: dataParamIds
     */
    @Override
    public Map<Long, DataParam4EquipmentExtendDTO> mapExtendByDataParamIds(List<Long> dataParamIds) throws ServiceException {
        List<DataParamEquipmentExtendDO> equipmentDataParamRelationList = baseMapper
                .selectList(Wrappers.<DataParamEquipmentExtendDO>lambdaQuery()
                        .in(DataParamEquipmentExtendDO::getDataParamId, dataParamIds));
        // 数据为空
        if (CollUtil.isEmpty(equipmentDataParamRelationList)) {
            return new HashMap<>();
        }

        Map<Long, DataParam4EquipmentExtendDTO> result = new HashMap<>();
        equipmentDataParamRelationList.forEach(item -> {
            DataParam4EquipmentExtendDTO equipmentDataParamExtendDTO = BeanUtils.copyToObject(item, DataParam4EquipmentExtendDTO.class);
            result.put(item.getDataParamId(), equipmentDataParamExtendDTO);
        });
        return result;
    }

//    /**
//     * 添加设备标签列表
//     *
//     * @param equipmentId 设备 ID
//     * @param labelIdList 标签 ID 列表
//     * @throws ServiceException 服务异常
//     */
//    @Override
//    public void addDataParamLabelList(Long equipmentId, List<ConfigLabelDTO> labelIdList) throws ServiceException {
//        List<Long> dataParamIdList = listDataParamIdRelation(equipmentId);
//
//        if (CollUtil.isEmpty(dataParamIdList)) {
//            return;
//        }
//
//        List<Long> newList = labelIdList.stream().map(ConfigLabelDTO::getLabelItemId).collect(Collectors.toList());
//
//        Long dataParamId1 = dataParamIdList.get(0);
//        List<ConfigDataParamLabelRelationDO> tempList = configDataParamLabelRelationDAO.selectList(Wrappers.<ConfigDataParamLabelRelationDO>lambdaQuery()
//                .eq(ConfigDataParamLabelRelationDO::getDataParamId, dataParamId1));
//
//        List<Long> oldList = tempList.stream().map(ConfigDataParamLabelRelationDO::getLableItemId).collect(Collectors.toList());
//
//        newList.removeAll(oldList);
//
//        if (CollUtil.isEmpty(newList)) {
//            return;
//        }
//
//        for (Long dataParamId : dataParamIdList) {
//            List<ConfigDataParamLabelRelationDO> list = new ArrayList<>();
//            for (Long labelItemId : newList) {
//                ConfigDataParamLabelRelationDO configDataParamLabelRelationDO = new ConfigDataParamLabelRelationDO();
//                configDataParamLabelRelationDO.setDataParamId(dataParamId);
//                configDataParamLabelRelationDO.setLableItemId(labelItemId);
//                list.add(configDataParamLabelRelationDO);
//            }
//            configDataParamLabelRelationDAO.insertBatch(list);
//        }
//    }



//    /**
//     * 删除设备标签列表
//     *
//     * @param equipmentId 设备 ID
//     * @param labelIdList 标签 ID 列表
//     * @throws ServiceException 服务异常
//     */
//    @Override
//    public void deleteDataParamLabelList(Long equipmentId, List<Long> labelIdList) throws ServiceException {
//        List<Long> dataParamIdList = listDataParamIdRelation(equipmentId);
//
//        if (CollUtil.isEmpty(dataParamIdList)) {
//            return;
//        }
//
//        for (Long dataParamId : dataParamIdList) {
//            configDataParamLabelRelationDAO.delete(Wrappers.<ConfigDataParamLabelRelationDO>lambdaQuery()
//                   .eq(ConfigDataParamLabelRelationDO::getDataParamId, dataParamId)
//                   .in(ConfigDataParamLabelRelationDO::getLableItemId, labelIdList));
//        }
//    }
}
